home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / lib / python2.6 / lib2to3 / pytree.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2009-11-11  |  29KB  |  891 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. """Python parse tree definitions.
  5.  
  6. This is a very concrete parse tree; we need to keep every token and
  7. even the comments and whitespace between tokens.
  8.  
  9. There's also a pattern matching implementation here.
  10. """
  11. __author__ = 'Guido van Rossum <guido@python.org>'
  12. import sys
  13. from StringIO import StringIO
  14. HUGE = 2147483647
  15. _type_reprs = { }
  16.  
  17. def type_repr(type_num):
  18.     if not _type_reprs:
  19.         python_symbols = python_symbols
  20.         import pygram
  21.         for name, val in python_symbols.__dict__.items():
  22.             if type(val) == int:
  23.                 _type_reprs[val] = name
  24.                 continue
  25.         
  26.     
  27.     return _type_reprs.setdefault(type_num, type_num)
  28.  
  29.  
  30. class Base(object):
  31.     '''Abstract base class for Node and Leaf.
  32.  
  33.     This provides some default functionality and boilerplate using the
  34.     template pattern.
  35.  
  36.     A node may be a subnode of at most one parent.
  37.     '''
  38.     type = None
  39.     parent = None
  40.     children = ()
  41.     was_changed = False
  42.     
  43.     def __new__(cls, *args, **kwds):
  44.         '''Constructor that prevents Base from being instantiated.'''
  45.         if not cls is not Base:
  46.             raise AssertionError, 'Cannot instantiate Base'
  47.         return object.__new__(cls)
  48.  
  49.     
  50.     def __eq__(self, other):
  51.         '''Compares two nodes for equality.
  52.  
  53.         This calls the method _eq().
  54.         '''
  55.         if self.__class__ is not other.__class__:
  56.             return NotImplemented
  57.         return self._eq(other)
  58.  
  59.     
  60.     def __ne__(self, other):
  61.         '''Compares two nodes for inequality.
  62.  
  63.         This calls the method _eq().
  64.         '''
  65.         if self.__class__ is not other.__class__:
  66.             return NotImplemented
  67.         return not self._eq(other)
  68.  
  69.     
  70.     def _eq(self, other):
  71.         '''Compares two nodes for equality.
  72.  
  73.         This is called by __eq__ and __ne__.  It is only called if the
  74.         two nodes have the same type.  This must be implemented by the
  75.         concrete subclass.  Nodes should be considered equal if they
  76.         have the same structure, ignoring the prefix string and other
  77.         context information.
  78.         '''
  79.         raise NotImplementedError
  80.  
  81.     
  82.     def clone(self):
  83.         '''Returns a cloned (deep) copy of self.
  84.  
  85.         This must be implemented by the concrete subclass.
  86.         '''
  87.         raise NotImplementedError
  88.  
  89.     
  90.     def post_order(self):
  91.         '''Returns a post-order iterator for the tree.
  92.  
  93.         This must be implemented by the concrete subclass.
  94.         '''
  95.         raise NotImplementedError
  96.  
  97.     
  98.     def pre_order(self):
  99.         '''Returns a pre-order iterator for the tree.
  100.  
  101.         This must be implemented by the concrete subclass.
  102.         '''
  103.         raise NotImplementedError
  104.  
  105.     
  106.     def set_prefix(self, prefix):
  107.         '''Sets the prefix for the node (see Leaf class).
  108.  
  109.         This must be implemented by the concrete subclass.
  110.         '''
  111.         raise NotImplementedError
  112.  
  113.     
  114.     def get_prefix(self):
  115.         '''Returns the prefix for the node (see Leaf class).
  116.  
  117.         This must be implemented by the concrete subclass.
  118.         '''
  119.         raise NotImplementedError
  120.  
  121.     
  122.     def replace(self, new):
  123.         '''Replaces this node with a new one in the parent.'''
  124.         if not self.parent is not None:
  125.             raise AssertionError, str(self)
  126.         if not new is not None:
  127.             raise AssertionError
  128.         l_children = []
  129.         found = False
  130.         for ch in self.parent.children:
  131.             if ch is self:
  132.                 if not not found:
  133.                     raise AssertionError, (self.parent.children, self, new)
  134.                 found = True
  135.                 continue
  136.             None if new is not None else None if not isinstance(new, list) else self.parent is not None
  137.             l_children.append(ch)
  138.         
  139.         if not found:
  140.             raise AssertionError, (self.children, self, new)
  141.         self.parent.changed()
  142.         self.parent.children = l_children
  143.         for x in new:
  144.             x.parent = self.parent
  145.         
  146.         self.parent = None
  147.  
  148.     
  149.     def get_lineno(self):
  150.         '''Returns the line number which generated the invocant node.'''
  151.         node = self
  152.         while not isinstance(node, Leaf):
  153.             if not node.children:
  154.                 return None
  155.             node = node.children[0]
  156.             continue
  157.             node.children
  158.         return node.lineno
  159.  
  160.     
  161.     def changed(self):
  162.         if self.parent:
  163.             self.parent.changed()
  164.         
  165.         self.was_changed = True
  166.  
  167.     
  168.     def remove(self):
  169.         """Remove the node from the tree. Returns the position of the node
  170.         in its parent's children before it was removed."""
  171.         if self.parent:
  172.             for i, node in enumerate(self.parent.children):
  173.                 if node is self:
  174.                     self.parent.changed()
  175.                     del self.parent.children[i]
  176.                     self.parent = None
  177.                     return i
  178.             
  179.         
  180.  
  181.     
  182.     def get_next_sibling(self):
  183.         """Return the node immediately following the invocant in their
  184.         parent's children list. If the invocant does not have a next
  185.         sibling, return None."""
  186.         if self.parent is None:
  187.             return None
  188.         for i, child in enumerate(self.parent.children):
  189.             if child is self:
  190.                 
  191.                 try:
  192.                     return self.parent.children[i + 1]
  193.                 except IndexError:
  194.                     self.parent is None
  195.                     self.parent is None
  196.                     return None
  197.                 
  198.  
  199.             self.parent is None<EXCEPTION MATCH>IndexError
  200.         
  201.  
  202.     
  203.     def get_prev_sibling(self):
  204.         """Return the node immediately preceding the invocant in their
  205.         parent's children list. If the invocant does not have a previous
  206.         sibling, return None."""
  207.         if self.parent is None:
  208.             return None
  209.         for i, child in enumerate(self.parent.children):
  210.             if child is self:
  211.                 if i == 0:
  212.                     return None
  213.                 return self.parent.children[i - 1]
  214.         
  215.  
  216.     
  217.     def get_suffix(self):
  218.         '''Return the string immediately following the invocant node. This
  219.         is effectively equivalent to node.get_next_sibling().get_prefix()'''
  220.         next_sib = self.get_next_sibling()
  221.         if next_sib is None:
  222.             return ''
  223.         return next_sib.get_prefix()
  224.  
  225.  
  226.  
  227. class Node(Base):
  228.     '''Concrete implementation for interior nodes.'''
  229.     
  230.     def __init__(self, type, children, context = None, prefix = None):
  231.         '''Initializer.
  232.  
  233.         Takes a type constant (a symbol number >= 256), a sequence of
  234.         child nodes, and an optional context keyword argument.
  235.  
  236.         As a side effect, the parent pointers of the children are updated.
  237.         '''
  238.         if not type >= 256:
  239.             raise AssertionError, type
  240.         self.type = type
  241.         self.children = list(children)
  242.         for ch in self.children:
  243.             if not ch.parent is None:
  244.                 raise AssertionError, repr(ch)
  245.             ch.parent = self
  246.         
  247.  
  248.     
  249.     def __repr__(self):
  250.         '''Returns a canonical string representation.'''
  251.         return '%s(%s, %r)' % (self.__class__.__name__, type_repr(self.type), self.children)
  252.  
  253.     
  254.     def __str__(self):
  255.         '''Returns a pretty string representation.
  256.  
  257.         This reproduces the input source exactly.
  258.         '''
  259.         return ''.join(map(str, self.children))
  260.  
  261.     
  262.     def _eq(self, other):
  263.         '''Compares two nodes for equality.'''
  264.         return (self.type, self.children) == (other.type, other.children)
  265.  
  266.     
  267.     def clone(self):
  268.         '''Returns a cloned (deep) copy of self.'''
  269.         return []([], [ ch.clone() for ch in self.children ])
  270.  
  271.     
  272.     def post_order(self):
  273.         '''Returns a post-order iterator for the tree.'''
  274.         for child in self.children:
  275.             for node in child.post_order():
  276.                 yield node
  277.             
  278.         
  279.         yield self
  280.  
  281.     
  282.     def pre_order(self):
  283.         '''Returns a pre-order iterator for the tree.'''
  284.         yield self
  285.         for child in self.children:
  286.             for node in child.post_order():
  287.                 yield node
  288.             
  289.         
  290.  
  291.     
  292.     def set_prefix(self, prefix):
  293.         '''Sets the prefix for the node.
  294.  
  295.         This passes the responsibility on to the first child.
  296.         '''
  297.         if self.children:
  298.             self.children[0].set_prefix(prefix)
  299.         
  300.  
  301.     
  302.     def get_prefix(self):
  303.         '''Returns the prefix for the node.
  304.  
  305.         This passes the call on to the first child.
  306.         '''
  307.         if not self.children:
  308.             return ''
  309.         return self.children[0].get_prefix()
  310.  
  311.     
  312.     def set_child(self, i, child):
  313.         """Equivalent to 'node.children[i] = child'. This method also sets the
  314.         child's parent attribute appropriately."""
  315.         child.parent = self
  316.         self.children[i].parent = None
  317.         self.children[i] = child
  318.         self.changed()
  319.  
  320.     
  321.     def insert_child(self, i, child):
  322.         """Equivalent to 'node.children.insert(i, child)'. This method also
  323.         sets the child's parent attribute appropriately."""
  324.         child.parent = self
  325.         self.children.insert(i, child)
  326.         self.changed()
  327.  
  328.     
  329.     def append_child(self, child):
  330.         """Equivalent to 'node.children.append(child)'. This method also
  331.         sets the child's parent attribute appropriately."""
  332.         child.parent = self
  333.         self.children.append(child)
  334.         self.changed()
  335.  
  336.  
  337.  
  338. class Leaf(Base):
  339.     '''Concrete implementation for leaf nodes.'''
  340.     prefix = ''
  341.     lineno = 0
  342.     column = 0
  343.     
  344.     def __init__(self, type, value, context = None, prefix = None):
  345.         '''Initializer.
  346.  
  347.         Takes a type constant (a token number < 256), a string value,
  348.         and an optional context keyword argument.
  349.         '''
  350.         if type <= type:
  351.             pass
  352.         elif not type < 256:
  353.             raise AssertionError, type
  354.         if context is not None:
  355.             (self.lineno, self.column) = (self.prefix,)
  356.         
  357.         self.type = type
  358.         self.value = value
  359.         if prefix is not None:
  360.             self.prefix = prefix
  361.         
  362.  
  363.     
  364.     def __repr__(self):
  365.         '''Returns a canonical string representation.'''
  366.         return '%s(%r, %r)' % (self.__class__.__name__, self.type, self.value)
  367.  
  368.     
  369.     def __str__(self):
  370.         '''Returns a pretty string representation.
  371.  
  372.         This reproduces the input source exactly.
  373.         '''
  374.         return self.prefix + str(self.value)
  375.  
  376.     
  377.     def _eq(self, other):
  378.         '''Compares two nodes for equality.'''
  379.         return (self.type, self.value) == (other.type, other.value)
  380.  
  381.     
  382.     def clone(self):
  383.         '''Returns a cloned (deep) copy of self.'''
  384.         return Leaf(self.type, self.value, (self.prefix, (self.lineno, self.column)))
  385.  
  386.     
  387.     def post_order(self):
  388.         '''Returns a post-order iterator for the tree.'''
  389.         yield self
  390.  
  391.     
  392.     def pre_order(self):
  393.         '''Returns a pre-order iterator for the tree.'''
  394.         yield self
  395.  
  396.     
  397.     def set_prefix(self, prefix):
  398.         '''Sets the prefix for the node.'''
  399.         self.changed()
  400.         self.prefix = prefix
  401.  
  402.     
  403.     def get_prefix(self):
  404.         '''Returns the prefix for the node.'''
  405.         return self.prefix
  406.  
  407.  
  408.  
  409. def convert(gr, raw_node):
  410.     '''Converts raw node information to a Node or Leaf instance.
  411.  
  412.     This is passed to the parser driver which calls it whenever a
  413.     reduction of a grammar rule produces a new complete node, so that
  414.     the tree is build strictly bottom-up.
  415.     '''
  416.     (type, value, context, children) = raw_node
  417.     if children or type in gr.number2symbol:
  418.         if len(children) == 1:
  419.             return children[0]
  420.         return Node(type, children, context = context)
  421.     return Leaf(type, value, context = context)
  422.  
  423.  
  424. class BasePattern(object):
  425.     '''A pattern is a tree matching pattern.
  426.  
  427.     It looks for a specific node type (token or symbol), and
  428.     optionally for a specific content.
  429.  
  430.     This is an abstract base class.  There are three concrete
  431.     subclasses:
  432.  
  433.     - LeafPattern matches a single leaf node;
  434.     - NodePattern matches a single node (usually non-leaf);
  435.     - WildcardPattern matches a sequence of nodes of variable length.
  436.     '''
  437.     type = None
  438.     content = None
  439.     name = None
  440.     
  441.     def __new__(cls, *args, **kwds):
  442.         '''Constructor that prevents BasePattern from being instantiated.'''
  443.         if not cls is not BasePattern:
  444.             raise AssertionError, 'Cannot instantiate BasePattern'
  445.         return object.__new__(cls)
  446.  
  447.     
  448.     def __repr__(self):
  449.         args = [
  450.             type_repr(self.type),
  451.             self.content,
  452.             self.name]
  453.         while args and args[-1] is None:
  454.             del args[-1]
  455.         return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr, args)))
  456.  
  457.     
  458.     def optimize(self):
  459.         '''A subclass can define this as a hook for optimizations.
  460.  
  461.         Returns either self or another node with the same effect.
  462.         '''
  463.         return self
  464.  
  465.     
  466.     def match(self, node, results = None):
  467.         '''Does this pattern exactly match a node?
  468.  
  469.         Returns True if it matches, False if not.
  470.  
  471.         If results is not None, it must be a dict which will be
  472.         updated with the nodes matching named subpatterns.
  473.  
  474.         Default implementation for non-wildcard patterns.
  475.         '''
  476.         if self.type is not None and node.type != self.type:
  477.             return False
  478.         if self.content is not None:
  479.             r = None
  480.             if results is not None:
  481.                 r = { }
  482.             
  483.             if not self._submatch(node, r):
  484.                 return False
  485.             if r:
  486.                 results.update(r)
  487.             
  488.         
  489.         if results is not None and self.name:
  490.             results[self.name] = node
  491.         
  492.         return True
  493.  
  494.     
  495.     def match_seq(self, nodes, results = None):
  496.         '''Does this pattern exactly match a sequence of nodes?
  497.  
  498.         Default implementation for non-wildcard patterns.
  499.         '''
  500.         if len(nodes) != 1:
  501.             return False
  502.         return self.match(nodes[0], results)
  503.  
  504.     
  505.     def generate_matches(self, nodes):
  506.         '''Generator yielding all matches for this pattern.
  507.  
  508.         Default implementation for non-wildcard patterns.
  509.         '''
  510.         r = { }
  511.         if nodes and self.match(nodes[0], r):
  512.             yield (1, r)
  513.         
  514.  
  515.  
  516.  
  517. class LeafPattern(BasePattern):
  518.     
  519.     def __init__(self, type = None, content = None, name = None):
  520.         '''Initializer.  Takes optional type, content, and name.
  521.  
  522.         The type, if given must be a token type (< 256).  If not given,
  523.         this matches any *leaf* node; the content may still be required.
  524.  
  525.         The content, if given, must be a string.
  526.  
  527.         If a name is given, the matching node is stored in the results
  528.         dict under that key.
  529.         '''
  530.         if type is not None:
  531.             if type <= type:
  532.                 pass
  533.             elif not type < 256:
  534.                 raise AssertionError, type
  535.         
  536.         if content is not None:
  537.             if not isinstance(content, basestring):
  538.                 raise AssertionError, repr(content)
  539.         
  540.         self.type = type
  541.         self.content = content
  542.         self.name = name
  543.  
  544.     
  545.     def match(self, node, results = None):
  546.         '''Override match() to insist on a leaf node.'''
  547.         if not isinstance(node, Leaf):
  548.             return False
  549.         return BasePattern.match(self, node, results)
  550.  
  551.     
  552.     def _submatch(self, node, results = None):
  553.         """Match the pattern's content to the node's children.
  554.  
  555.         This assumes the node type matches and self.content is not None.
  556.  
  557.         Returns True if it matches, False if not.
  558.  
  559.         If results is not None, it must be a dict which will be
  560.         updated with the nodes matching named subpatterns.
  561.  
  562.         When returning False, the results dict may still be updated.
  563.         """
  564.         return self.content == node.value
  565.  
  566.  
  567.  
  568. class NodePattern(BasePattern):
  569.     wildcards = False
  570.     
  571.     def __init__(self, type = None, content = None, name = None):
  572.         """Initializer.  Takes optional type, content, and name.
  573.  
  574.         The type, if given, must be a symbol type (>= 256).  If the
  575.         type is None this matches *any* single node (leaf or not),
  576.         except if content is not None, in which it only matches
  577.         non-leaf nodes that also match the content pattern.
  578.  
  579.         The content, if not None, must be a sequence of Patterns that
  580.         must match the node's children exactly.  If the content is
  581.         given, the type must not be None.
  582.  
  583.         If a name is given, the matching node is stored in the results
  584.         dict under that key.
  585.         """
  586.         if type is not None:
  587.             if not type >= 256:
  588.                 raise AssertionError, type
  589.         
  590.         if content is not None:
  591.             if not not isinstance(content, basestring):
  592.                 raise AssertionError, repr(content)
  593.             content = list(content)
  594.             for i, item in enumerate(content):
  595.                 not isinstance(content, basestring) if not isinstance(item, BasePattern) else isinstance(item, BasePattern)
  596.             
  597.         
  598.         self.type = type
  599.         self.content = content
  600.         self.name = name
  601.  
  602.     
  603.     def _submatch(self, node, results = None):
  604.         """Match the pattern's content to the node's children.
  605.  
  606.         This assumes the node type matches and self.content is not None.
  607.  
  608.         Returns True if it matches, False if not.
  609.  
  610.         If results is not None, it must be a dict which will be
  611.         updated with the nodes matching named subpatterns.
  612.  
  613.         When returning False, the results dict may still be updated.
  614.         """
  615.         if self.wildcards:
  616.             for c, r in generate_matches(self.content, node.children):
  617.                 if c == len(node.children):
  618.                     if results is not None:
  619.                         results.update(r)
  620.                     
  621.                     return True
  622.             
  623.             return False
  624.         if len(self.content) != len(node.children):
  625.             return False
  626.         for subpattern, child in zip(self.content, node.children):
  627.             if not subpattern.match(child, results):
  628.                 return False
  629.         
  630.         return True
  631.  
  632.  
  633.  
  634. class WildcardPattern(BasePattern):
  635.     '''A wildcard pattern can match zero or more nodes.
  636.  
  637.     This has all the flexibility needed to implement patterns like:
  638.  
  639.     .*      .+      .?      .{m,n}
  640.     (a b c | d e | f)
  641.     (...)*  (...)+  (...)?  (...){m,n}
  642.  
  643.     except it always uses non-greedy matching.
  644.     '''
  645.     
  646.     def __init__(self, content = None, min = 0, max = HUGE, name = None):
  647.         """Initializer.
  648.  
  649.         Args:
  650.             content: optional sequence of subsequences of patterns;
  651.                      if absent, matches one node;
  652.                      if present, each subsequence is an alternative [*]
  653.             min: optinal minumum number of times to match, default 0
  654.             max: optional maximum number of times tro match, default HUGE
  655.             name: optional name assigned to this match
  656.  
  657.         [*] Thus, if content is [[a, b, c], [d, e], [f, g, h]] this is
  658.             equivalent to (a b c | d e | f g h); if content is None,
  659.             this is equivalent to '.' in regular expression terms.
  660.             The min and max parameters work as follows:
  661.                 min=0, max=maxint: .*
  662.                 min=1, max=maxint: .+
  663.                 min=0, max=1: .?
  664.                 min=1, max=1: .
  665.             If content is not None, replace the dot with the parenthesized
  666.             list of alternatives, e.g. (a b c | d e | f g h)*
  667.         """
  668.         if min <= min and max <= max:
  669.             pass
  670.         elif not max <= HUGE:
  671.             raise AssertionError, (min, max)
  672.         self.content = content
  673.         self.min = min
  674.         self.max = max
  675.         self.name = name
  676.  
  677.     
  678.     def optimize(self):
  679.         '''Optimize certain stacked wildcard patterns.'''
  680.         subpattern = None
  681.         if self.content is not None and len(self.content) == 1 and len(self.content[0]) == 1:
  682.             subpattern = self.content[0][0]
  683.         
  684.         if self.min <= 1 and isinstance(subpattern, WildcardPattern) and subpattern.min <= 1 and self.name == subpattern.name:
  685.             return WildcardPattern(subpattern.content, self.min * subpattern.min, self.max * subpattern.max, subpattern.name)
  686.         return self
  687.  
  688.     
  689.     def match(self, node, results = None):
  690.         '''Does this pattern exactly match a node?'''
  691.         return self.match_seq([
  692.             node], results)
  693.  
  694.     
  695.     def match_seq(self, nodes, results = None):
  696.         '''Does this pattern exactly match a sequence of nodes?'''
  697.         for c, r in self.generate_matches(nodes):
  698.             if c == len(nodes):
  699.                 if results is not None:
  700.                     results.update(r)
  701.                     if self.name:
  702.                         results[self.name] = list(nodes)
  703.                     
  704.                 
  705.                 return True
  706.         
  707.         return False
  708.  
  709.     
  710.     def generate_matches(self, nodes):
  711.         '''Generator yielding matches for a sequence of nodes.
  712.  
  713.         Args:
  714.             nodes: sequence of nodes
  715.  
  716.         Yields:
  717.             (count, results) tuples where:
  718.             count: the match comprises nodes[:count];
  719.             results: dict containing named submatches.
  720.         '''
  721.         if self.content is None:
  722.             for count in xrange(self.min, 1 + min(len(nodes), self.max)):
  723.                 r = { }
  724.                 if self.name:
  725.                     r[self.name] = nodes[:count]
  726.                 
  727.                 yield (count, r)
  728.             
  729.         elif self.name == 'bare_name':
  730.             yield self._bare_name_matches(nodes)
  731.         else:
  732.             save_stderr = sys.stderr
  733.             sys.stderr = StringIO()
  734.             
  735.             try:
  736.                 for count, r in self._recursive_matches(nodes, 0):
  737.                     if self.name:
  738.                         r[self.name] = nodes[:count]
  739.                     
  740.                     yield (count, r)
  741.             except RuntimeError:
  742.                 for count, r in self._iterative_matches(nodes):
  743.                     if self.name:
  744.                         r[self.name] = nodes[:count]
  745.                     
  746.                     yield (count, r)
  747.                 
  748.             finally:
  749.                 sys.stderr = save_stderr
  750.  
  751.  
  752.     
  753.     def _iterative_matches(self, nodes):
  754.         '''Helper to iteratively yield the matches.'''
  755.         nodelen = len(nodes)
  756.         if 0 >= self.min:
  757.             yield (0, { })
  758.         
  759.         results = []
  760.         for alt in self.content:
  761.             for c, r in generate_matches(alt, nodes):
  762.                 yield (c, r)
  763.                 results.append((c, r))
  764.             
  765.         
  766.         while results:
  767.             new_results = []
  768.             for c0, r0 in results:
  769.                 if c0 < nodelen and c0 <= self.max:
  770.                     for alt in self.content:
  771.                         for c1, r1 in generate_matches(alt, nodes[c0:]):
  772.                             if c1 > 0:
  773.                                 r = { }
  774.                                 r.update(r0)
  775.                                 r.update(r1)
  776.                                 yield (c0 + c1, r)
  777.                                 new_results.append((c0 + c1, r))
  778.                                 continue
  779.                         
  780.                     
  781.             
  782.             results = new_results
  783.  
  784.     
  785.     def _bare_name_matches(self, nodes):
  786.         '''Special optimized matcher for bare_name.'''
  787.         count = 0
  788.         r = { }
  789.         done = False
  790.         max = len(nodes)
  791.         while not done and count < max:
  792.             done = True
  793.             for leaf in self.content:
  794.                 if leaf[0].match(nodes[count], r):
  795.                     count += 1
  796.                     done = False
  797.                     break
  798.                     continue
  799.             
  800.         r[self.name] = nodes[:count]
  801.         return (count, r)
  802.  
  803.     
  804.     def _recursive_matches(self, nodes, count):
  805.         '''Helper to recursively yield the matches.'''
  806.         if not self.content is not None:
  807.             raise AssertionError
  808.         if count < self.max:
  809.             for alt in self.content:
  810.                 for c0, r0 in generate_matches(alt, nodes):
  811.                     for c1, r1 in self._recursive_matches(nodes[c0:], count + 1):
  812.                         r = { }
  813.                         r.update(r0)
  814.                         r.update(r1)
  815.                         yield (c0 + c1, r)
  816.                         None if count >= self.min else self.content is not None
  817.                     
  818.                 
  819.             
  820.         
  821.  
  822.  
  823.  
  824. class NegatedPattern(BasePattern):
  825.     
  826.     def __init__(self, content = None):
  827.         """Initializer.
  828.  
  829.         The argument is either a pattern or None.  If it is None, this
  830.         only matches an empty sequence (effectively '$' in regex
  831.         lingo).  If it is not None, this matches whenever the argument
  832.         pattern doesn't have any matches.
  833.         """
  834.         if content is not None:
  835.             if not isinstance(content, BasePattern):
  836.                 raise AssertionError, repr(content)
  837.         
  838.         self.content = content
  839.  
  840.     
  841.     def match(self, node):
  842.         return False
  843.  
  844.     
  845.     def match_seq(self, nodes):
  846.         return len(nodes) == 0
  847.  
  848.     
  849.     def generate_matches(self, nodes):
  850.         if self.content is None:
  851.             if len(nodes) == 0:
  852.                 yield (0, { })
  853.             
  854.         else:
  855.             for c, r in self.content.generate_matches(nodes):
  856.                 return None
  857.             
  858.             yield (0, { })
  859.  
  860.  
  861.  
  862. def generate_matches(patterns, nodes):
  863.     '''Generator yielding matches for a sequence of patterns and nodes.
  864.  
  865.     Args:
  866.         patterns: a sequence of patterns
  867.         nodes: a sequence of nodes
  868.  
  869.     Yields:
  870.         (count, results) tuples where:
  871.         count: the entire sequence of patterns matches nodes[:count];
  872.         results: dict containing named submatches.
  873.         '''
  874.     if not patterns:
  875.         yield (0, { })
  876.     else:
  877.         p = patterns[0]
  878.         rest = patterns[1:]
  879.         for c0, r0 in p.generate_matches(nodes):
  880.             if not rest:
  881.                 yield (c0, r0)
  882.                 continue
  883.             for c1, r1 in generate_matches(rest, nodes[c0:]):
  884.                 r = { }
  885.                 r.update(r0)
  886.                 r.update(r1)
  887.                 yield (c0 + c1, r)
  888.             
  889.         
  890.  
  891.